/*
 * Copyright 2025 arisgo@163.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.arisgo.cloud.auth.sys.service.impl;

import com.arisgo.cloud.auth.login.granter.configurer.ManagerConfigurer;
import com.arisgo.cloud.auth.sys.entity.TenantUser;
import com.arisgo.cloud.auth.sys.entity.User;
import com.arisgo.cloud.auth.sys.mapper.TenantUserMapper;
import com.arisgo.cloud.auth.sys.mapper.UserMapper;
import com.arisgo.cloud.auth.sys.service.UserService;
import com.arisgo.cloud.auth.sys.vo.UserVo;
import com.arisgo.cloud.common.Pagination;
import com.arisgo.cloud.common.utils.AssertUtil;
import com.arisgo.cloud.common.utils.CipherUtil;
import com.arisgo.cloud.web.mybatis.service.CloudServiceImpl;
import com.arisgo.cloud.web.param.Paging;
import com.arisgo.cloud.web.param.Param;
import com.arisgo.cloud.web.param.Search;
import com.arisgo.cloud.web.utils.RequestUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

/**
 * 用户
 *
 * @author Arisgo
 * @since 2024-08-03
 */
@Service
@AllArgsConstructor
public class UserServiceImpl extends CloudServiceImpl<UserMapper, User, UserVo> implements UserService {

    private final ManagerConfigurer managerConfigurer;
    private final TenantUserMapper tenantUserMapper;

    @Override
    public User getInstanceModel() {
        return new User();
    }

    @Override
    public UserVo getInstanceVo() {
        return new UserVo();
    }

    @Override
    public boolean isExistsUser(String username) {
        AssertUtil.hasLength(username, "用户名为空！");
        Map<String, Object> params = Maps.newHashMap();
        params.put(User.ACCOUNT, username);
        params.put(User.IS_DELETED, 0);
        return !CollectionUtils.isEmpty(this.findByParams(params));
    }

    @Override
    public UserVo findUserByAccount(String username) {
        return this.mapper.findUserByAccount(username);
    }

    @Override
    public Pagination<UserVo> pageUser(Paging paging) {
        // 超级管理员登陆，只查询账户
        if (managerConfigurer.getUserId().equals(RequestUtil.getUserId())) {
            return this.page(paging);
        }
        // 非超级管理员登陆，查询租户下的账号
        paging.addTenantIdParam(RequestUtil.getTenantId());
        PageHelper.startPage(paging.getPageNo(), paging.getPageSize());
        PageInfo<UserVo> page = new PageInfo<>(this.mapper.findUserByParams(paging.convertMap()));
        return Pagination.creator(page.getPageNum(), page.getPageSize(), page.getTotal(), page.getList());
    }

    @Override
    public Boolean insert(String username) {
        // 账号校验
        AssertUtil.hasLength(username, "用户名为空！");
        AssertUtil.isTrue(!managerConfigurer.getAccount().equals(username), "账号已存在！");

        Long userId = RequestUtil.getUserId();
        Long tenantId = RequestUtil.getTenantId();
        User user = this.mapper.selectOneByQuery(Search.creator(Param.creator(User.ACCOUNT, username)).buildWrapper());
        if (user != null) {
            AssertUtil.isTrue(!managerConfigurer.getUserId().equals(userId), "账号已存在！");

            Search search = Search.creator(Param.creator(TenantUser.USER_ID, user.getId()), Param.creator(TenantUser.TENANT_ID, tenantId));
            TenantUser tenantUser = tenantUserMapper.selectOneByQuery(search.buildWrapper());
            AssertUtil.isNull(tenantUser, "账号已存在！");
            // 关联账号
            tenantUser = new TenantUser();
            tenantUser.setUserId(user.getId());
            tenantUser.setTenantId(tenantId);
            tenantUser.setStatus(-1);
            tenantUserMapper.insert(tenantUser);
            return true;
        }

        // 新增账号
        user = new User();
        user.setAccount(username);
        user.setNickname(username);
        user.setPassword(CipherUtil.SHA.encode("cloud@2025"));
        user.setStatus(-1);
        if (managerConfigurer.getUserId().equals(userId)) {
            // 超级管理员账号，新增账号
            this.mapper.insert(user);
        } else {
            // 新增账号
            user.setTenantId(tenantId);
            this.mapper.insert(user);
            // 关联账号
            TenantUser tenantUser = new TenantUser();
            tenantUser.setUserId(user.getId());
            tenantUser.setTenantId(tenantId);
            tenantUser.setStatus(-1);
            tenantUserMapper.insert(tenantUser);

        }
        return true;
    }

    @Override
    public Boolean modify(Long id, Integer status) {
        // 超级管理员，修改user表中的用户状态
        if (managerConfigurer.getUserId().equals(RequestUtil.getUserId())) {
            User user = this.mapper.selectOneById(id);
            AssertUtil.notNull(user, "账号不存在！");
            user.setStatus(status);
            this.mapper.update(user);
        } else {
            // 非超级管理员，修改tenant_user表中用户状态
            Search search = Search.creator(Param.creator(TenantUser.USER_ID, id), Param.creator(TenantUser.TENANT_ID, RequestUtil.getTenantId()));
            TenantUser tenantUser = tenantUserMapper.selectOneByQuery(search.buildWrapper());
            AssertUtil.notNull(tenantUser, "账号不存在！");
            tenantUser.setStatus(status);
            tenantUserMapper.update(tenantUser);
        }
        return true;
    }

    @Override
    public Boolean drop(Long id) {
        return drop(Lists.newArrayList(id));
    }

    @Override
    public Boolean drop(List<Long> ids) {
        // 超级管理员操作user
        if (managerConfigurer.getUserId().equals(RequestUtil.getUserId())) {
            this.mapper.batchUptIsDeleted(ids, true);
        } else {
            // 非超级管理员，修改tenant_user表中用户状态
            tenantUserMapper.batchUptIsDeleted(RequestUtil.getTenantId(), ids, true);
        }
        return true;
    }

    @Override
    public Boolean del(List<Long> ids) {
        // 超级管理员操作user
        if (managerConfigurer.getUserId().equals(RequestUtil.getUserId())) {
            this.mapper.deleteBatchByIds(ids);
        } else {
            // 非超级管理员，修改tenant_user表中用户状态
            tenantUserMapper.batchDelete(RequestUtil.getTenantId(), ids);
        }
        return true;
    }

    @Override
    public List<UserVo> findUserByParams(Search search) {
        if (managerConfigurer.getUserId().equals(RequestUtil.getUserId())) {
            return findByParams(search);
        } else {
            // 非超级管理员，修改tenant_user表中用户状态
            search.addTenantIdParam(RequestUtil.getTenantId());
            return this.mapper.findUserByParams(search.convertMap());
        }
    }

    @Override
    public UserVo findUserById(Long id) {
        if (managerConfigurer.getUserId().equals(RequestUtil.getUserId())) {
            return findById(id);
        } else {
            // 非超级管理员，修改tenant_user表中用户状态
            Search search = Search.creator(Param.creator(TenantUser.TENANT_ID, RequestUtil.getTenantId()), Param.creator(TenantUser.USER_ID, id));
            List<UserVo> vos = this.mapper.findUserByParams(search.convertMap());
            if (CollectionUtils.isEmpty(vos)) {
                return null;
            } else if (vos.size() == 1) {
                return vos.get(0);
            } else {
                throw new RuntimeException("多条数据！");
            }
        }
    }

    @Override
    public Boolean isLock(Long id, Integer status) {
        AssertUtil.notNull(id, "账号不存在！");
        AssertUtil.notNull(status, "参数为空！");
        this.mapper.isLock(id, status);
        return true;
    }
}
